package com.ymttest.utils;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.junit.Ignore;
import org.junit.experimental.categories.Category;

import com.ymt.core.tool.Logger;



public class ExportTestCase {

	private final String PATH = "/src/com/ymatou/iapi/godmch";

	//    private final String PATH = "/src/com/ymatou/iapi/mqpublish";
	//com.ymatou.iapi.marketingmanage
	/**
	 * 用于返回一个class所有的Junit Test方法s
	 * 
	 * @param ClassName 类名
	 * @return List<Method> Methods
	 */

	private ArrayList<TestCaseBean> testCases = new ArrayList<TestCaseBean>();

	public List<Method> getTestMethods(String ClassName) {
		List<Method> m = new ArrayList<Method>();
		try {
			Method[] ms = Class.forName(ClassName).getDeclaredMethods();
			for (Method m1 : ms) {
				Annotation[] sa = m1.getAnnotations();
				if (m1.getName().startsWith("Tc_")) {
					m.add(m1);
				}
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return m;
	}

	// 获取url 地址 串
	public String getFeild(String ClassName) {
		String url = "";
		try {
			if (ClassName.endsWith("Call")) {
				Field field = Class.forName(ClassName)
						.getDeclaredField("opurl");
				field.setAccessible(true);
				url = field.get(null).toString();
				return url;
			} else {
				if (ClassName.indexOf("Ts_") > 0) {
					Field[] fs = Class.forName(ClassName).getDeclaredFields();
					for (Field f : fs) {
						/*
						 * Logger.debug("name:" + f.getName()); Logger.debug("field:" +
						 * f.toString());
						 */
						String[] s = f.toString().split(" ");
						if (s.length < 4)
							continue;
						if (s[2].endsWith("Call")) {
							return getFeild(s[2]);
						}
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return url;
	}

	public void analysitCase() {
		// 移除文件AnalysisCase
		TestDataManager.removeFile("./AnalysisCase");
		// 获取文件列表 \\src\\com\\ymt\\testcase
		ArrayList<String> flist = TestDataManager.getFilelist(System
				.getProperty("user.dir") + PATH);
		// 总case
		int caseNum = 1;

		for (String fname : flist) {
			// 获取文件内容
			if (!(fname.lastIndexOf(".java") > 0)) {
				Logger.debug(fname + "文件跳过解析！");
				continue;
			}
			// 获取文件内容
			if (!fname.contains("Ts_")) {
				// Logger.debug(fname + "不是Ts_测试用例文件跳过解析！");
				continue;
			}
			List<String> texts = TestDataManager.getLines(fname);
			List<String> caseDescriptionList = new ArrayList<String>();
			String suiteDescription = "";
			Logger.debug("fname:" + fname);

			for (int i = 0; i < texts.size(); i++) {

				String s = texts.get(i);

				if (s.trim().length() >= 23
						&& s.trim().substring(0, 23)
								.equals("Logger.createResultFile")) {
					s = s.trim();
					suiteDescription = s.substring(25, s.lastIndexOf("\""));
				}
				// Logger.generateResult需要参数
				//Logger.debug("s:" + s);
				if (s.trim().length() >= 21
						&& s.trim().substring(0, 21)
								.equals("Logger.generateResult")) {
					String temp = s.substring(22, s.lastIndexOf(")"));
					if (temp.length() <= 2) {
						Logger.debug("Logger.generateResult缺少数据:" + fname);
					}
				}
				// Logger.debug("s:" + s);
				// 获取 Logger.start 中的注释 至caseDescriptionList
				// 应该一个文件由多少的Test就有多少个Logger.start
				if (s.trim().length() >= 15
						&& s.trim().substring(0, 12).equals("Logger.start")) {
					try {

						s = s.substring(16, s.lastIndexOf("\""));
						s = s.substring(s.indexOf("\"") + 1);

					} catch (Exception e) {

						Logger.info(String
								.format("######## fname: \n%s \n 第 %s 行 Logger.start 格式不对",
										fname, i + 1));

						s = String.format("第 %s 行 Logger.start 格式不对", i + 1);
					}

					caseDescriptionList.add(s);
				}
			}
			// 获取文件名 format 成 class包格式
			// 例如：com.ymt.testcase.api.app.order.Ts_GetPayBankList
			fname = fname.substring(fname.indexOf("com"), fname.length() - 5)
					.replace(File.separator, ".");

			// 获取class方法列表
			List<Method> list = getTestMethods(fname);

			list.sort((a, b) -> {
				return a.getName().compareTo(b.getName());

			});

			int i = 0;
			for (Method method : list) {
				String[] tf = fname.split("_");
				String[] mf = method.getName().split("_");
				// 验证class Ts开头 非testcase不应该放在 src\\com\\ymt\\testcase
				if (!fname.substring(fname.lastIndexOf(".") + 1)
						.substring(0, 2).equals("Ts")) {
					Logger.debug("Ts格式错误:" + fname + ":" + method.getName());
				}
				// 验证所有@Test Tc开头
				if (!method.getName().substring(0, 2).equals("Tc")) {
					Logger.debug("Tc格式错误:" + fname + ":" + method.getName());
				}
				// 验证name 同文件 的 Ts Tc 名字应该一致
				if (!tf[tf.length - 1].equals(mf[mf.length - 2])) {
					Logger.debug("name格式错误:" + fname + ":" + method.getName());
				}
				String level = "";
				TestCaseBean Tc = new TestCaseBean();

				Annotation[] ans = method.getAnnotations();
				boolean haslevel = false;
				// Logger.debug("method:"+method.getName());
				// Logger.debug("hasAns:"+hasAns);
				// Logger.debug("hasAns length:"+ans.length);

				if (method.isAnnotationPresent(Ignore.class)) {
					// cancelNum++;
					Tc.setComment("ignore");
				}
				if (ans.length < 3) {
					// ignoreNum++;
					Tc.setComment("cancel");
				}
				for (Annotation annotation : ans) {
					if (annotation.annotationType().equals(Category.class)) {
						level = annotation.toString();
						level = level.substring(level.indexOf("tag.") + 4,
								level.lastIndexOf("]"));
						haslevel = true;
					}
				}
				if (!haslevel) {
					Logger.debug("没有找到合适的case level:" + fname + ":"
							+ method.getName());
				}
				// 获取url
				String url = getFeild(fname);
				try {
					// 分析结果写入文件
					TestDataManager.appendFileToLine("./AnalysisCase",
							fname + "	" + url + " " + suiteDescription + "	"
									+ method.getName() + "	"
									+ caseDescriptionList.get(i) + "	" + level);

					Tc.setCaseNum(caseNum);
					Tc.setUrl(url);
					Tc.setSuiteName(fname);
					Tc.setSutieDesc(suiteDescription);
					Tc.setCaseName(method.getName());
					Tc.setCaseDesc(caseDescriptionList.get(i));
					testCases.add(Tc);
					i++;
				} catch (Exception e) {
					Logger.debug(fname + ":" + method + ":" + i + ":"
							+ e.getMessage());
				}
			}
			caseNum++;
		}
		Logger.debug("Analysis Case completely!");
	}
	public void writeToExcel() {
		this.analysitCase();
		new ExcleUtil().writeResult(testCases);
	}

	public static void main(String[] args) {
		ExportTestCase tc = new ExportTestCase();
		tc.writeToExcel();
		// tc.analysitCase();
		// Logger.debug("url:"+tc.getFeild("com.ymatou."));
	}

}
